class FromDict(object):
    _dict = {}
    required = {}
    def __init__(self, _dict=None):
        if _dict:
            self.fromdict(_dict)

    def fromdict(self, _dict):
        for key in self._dict:
            try:
                if key in self.required :
                    self._dict[key] =self.required[key](self._dict[key])
                self._dict[key] = _dict[key]
            except IndexError as ie:
                print(ie)
                raise(ie)

    def __getattribute__(self, key):
        if key in self._dict.keys():
            return self._dict[key]
        else:
            raise IndexError

    def __str__(self):
        return str(self._dict)


class Project(FromDict):
    _dict = {
        "name": "",
        "path": "",
        "url": "",
        "git_ssh_url": "",
        "git_http_url": "",
        "git_svn_url": "",
        "namespace": "",
        "name_with_namespace": "",
        "path_with_namespace": "",
        "default_branch": ""
    }


class Author(FromDict):
    _dict = {
        "name": "",
         "email": "",
        "time": ""
    }
class User(FromDict):
    _dict = {
                "name": "",
                "email": "",
                "time": ""
            }


class Commit(FromDict):
    _dict = {
        "id": "",
        "message": "",
        "timestamp": "",
        "url": "",
        "author": None
    }
    required = {
        "author":Author
    }
class ListWrapper(list):
    def __init__(self, cls,items):
        self.items = [cls(x) for x in items] 
    def __iter__(self):
        return iter(self.items)

class Push(FromDict):
    _dict = {
        "before": "",
        "after": "",
        "ref": "",
        "user_id": 1,
        "user_name": "",
        "user": None,
        "repository": None,
        "commits": [],
        "total_commits_count": 1,
        "commits_more_than_ten": False,
        "project": None,
        "hook_name": "",
        "password": ""
        }
    required = {
        "commits":ListWrapper(Author,)

    }

    def __init__(self):
        self.before = ''
